#ifndef __Collections_Comparer_H__
#define __Collections_Comparer_H__

///<summary>
/// Comparer<T>
///</summary>
//+ requires: Collections_IComparer(T)
#define Collections_Comparer(T) bindT(Collections_Comparer,T)
#define Declare_Collections_Comparer(T, Ti) \
	enum { \
		_Collections_Comparer_##T##VIndex_Compare, \
		_Collections_Comparer_##T##VIndexNext, \
	}; \
	public abstract_ classTV(Collections_Comparer,T,System_Object,classInterface(Collections_IComparer(T)), \
		public abstractT(Collections_Comparer,T,int_,Compare, Ti x, Ti y); \
	,); \
	Declare_DefaultCtorT(protected,Collections_Comparer,T) \
	public static_ Collections_Comparer(T) *spaceT(Collections_Comparer,T,getDefault)();
#define Implement_Collections_Comparer(T, Ti) \
	/*[ Compare ] */ \
	private_ __device__ int_ spaceT(_cc_,T,Compare)(Collections_IComparer(T) *t, Ti x, Ti y) \
	{ \
		if (x == nullT(Ti)) \
		{ \
			if (y != nullT(Ti)) \
			{ \
				return -1; \
			} \
			return 0; \
		} \
		if (y == nullT(Ti)) \
		{ \
			return 1; \
		} \
		if (is(__boxT(Ti,x),Ti) && is(__boxT(Ti,y),Ti)) \
		{ \
			return vcallT(Collections_Comparer,T,t,Compare, x, y); \
		} \
		throw(ArgumentException,InvalidArgumentForComparison); \
	} \
	Implement_TypeTV(Collections_Comparer,T,System_Object,typeInterface(Collections_IComparer(T)), \
		vtable = t->Collections_IComparer(T).__vtable; \
		vtable[_Collections_IComparer_##T##VIndex_Compare] = (System_ObjectVector)&spaceT(_cc_,T,Compare); \
	) \
	Implement_DefaultCtorT(Collections_Comparer,T,System_Object) \
		private static_ Collections_Comparer(T) *spaceT(Collections_Comparer,T,s_defaultComparer) = nullT(Collections_Comparer(T)*); \
	\
	/*[ CreateComparer ]*/ \
	private __device__ static_ Collections_Comparer(T) *spaceT(Collections_Comparer,T,CreateComparer)() \
	{ \
		return nullT(Collections_Comparer(T)*); \
	} \
	\
	/*[ Default ]*/ \
	public __device__ static_ Collections_Comparer(T) *spaceT(Collections_Comparer,T,getDefault)() \
	{ \
		Collections_Comparer(T) *defaultComparer = spaceT(Collections_Comparer,T,s_defaultComparer); \
		if (defaultComparer == null) \
		{ \
			spaceT(Collections_Comparer,T,s_defaultComparer) = defaultComparer = spaceT(Collections_Comparer,T,CreateComparer)(); \
		} \
		return defaultComparer; \
	}

#endif /* __Collections_Comparer_H__ */
